package com.supermap.desktop.ui.controls;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceAdapter;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.Beans;
import java.io.IOException;
import java.util.HashMap;

import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

import com.supermap.data.Dataset;
import com.supermap.data.DatasetType;
import com.supermap.mapping.Layer;
import com.supermap.mapping.LayerAddedEvent;
import com.supermap.mapping.LayerAddedListener;
import com.supermap.mapping.LayerGroup;
import com.supermap.mapping.LayerGroupAddedEvent;
import com.supermap.mapping.LayerGroupAddedListener;
import com.supermap.mapping.LayerGroupRemovedEvent;
import com.supermap.mapping.LayerGroupRemovedListener;
import com.supermap.mapping.LayerRemovedEvent;
import com.supermap.mapping.LayerRemovedListener;
import com.supermap.mapping.LayerSettingImage;
import com.supermap.mapping.Map;
import com.supermap.mapping.Theme;
import com.supermap.mapping.ThemeGraph;
import com.supermap.mapping.ThemeGraphItem;
import com.supermap.mapping.ThemeGridRange;
import com.supermap.mapping.ThemeGridRangeItem;
import com.supermap.mapping.ThemeGridUnique;
import com.supermap.mapping.ThemeGridUniqueItem;
import com.supermap.mapping.ThemeLabel;
import com.supermap.mapping.ThemeLabelItem;
import com.supermap.mapping.ThemeRange;
import com.supermap.mapping.ThemeRangeItem;
import com.supermap.mapping.ThemeUnique;
import com.supermap.mapping.ThemeUniqueItem;

/**
 * 图层管理树控件
 * 
 * @author xuzw
 *
 */
public class LayersTree extends JTree {
	private Map currentMap = null;
	private LayerAddedListener layerAddedListener = null;
	private LayerRemovedListener layerRemovedListener = null;
	private LayerGroupAddedListener layerGroupAddedListener = null;
	private LayerGroupRemovedListener layerGroupRemovedListener = null;

	private KeyAdapter keyAdapter = null;
	private MouseAdapter mouseAdapter = null;

	private DragSource dragSource;
	private int draggedNodeIndex = -1;
	private int dropTargetNodeIndex = -1;

	private DefaultMutableTreeNode dropTargetNode = null;
	private DefaultMutableTreeNode draggedNode = null;

	private static DataFlavor localObjectFlavor;
	private static DataFlavor[] supportedFlavors = { localObjectFlavor };

	static {
		try {
			localObjectFlavor = new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType);
		} catch (ClassNotFoundException cnfe) {
			cnfe.printStackTrace();
		}
	}

	public LayersTree() {
		super();
		this.setModel(new DefaultTreeModel(new DefaultMutableTreeNode(new Map())));
		this.setEditable(true);
		this.setRootVisible(false);
		this.setShowsRootHandles(true);
		initDrag();
	}

	public LayersTree(Map map) {
		super();
		if (map == null) {
			TreeNodeData data = new TreeNodeData("", NodeDataType.UNKNOWN);
			this.setModel(new DefaultTreeModel(new DefaultMutableTreeNode(data)));
		} else {
			this.currentMap = map;
			this.setModel(getTreeModel());
			LayersTreeCellRenderer cellRenderer = new LayersTreeCellRenderer();
			this.setCellRenderer(cellRenderer);
			this.setCellEditor(new LayersTreeCellEditor(this, cellRenderer));
			this.registerListeners();
		}
		this.setEditable(true);
		this.setRootVisible(false);
		this.setShowsRootHandles(true);
		initDrag();
	}

	private void initDrag() {
		dragSource = DragSource.getDefaultDragSource();
		dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, new LayersTreeDragGestureListener());
		new DropTarget(this, new LayersTreeDropTargetAdapter());
	}

	public Map getMap() {
		return currentMap;
	}

	public void setMap(Map map) {
		if (currentMap != null && !currentMap.equals(map)) {
			unRegisterListeners();
		}
		
		if (currentMap == null || !currentMap.equals(map)) {
			currentMap = map;
			if (currentMap == null) {
				TreeNodeData data = new TreeNodeData("", NodeDataType.UNKNOWN);
				this.setModel(new DefaultTreeModel(new DefaultMutableTreeNode(data)));
			} else {
				this.setModel(getTreeModel());
				LayersTreeCellRenderer cellRenderer = new LayersTreeCellRenderer();
				this.setCellRenderer(cellRenderer);
				this.setCellEditor(new LayersTreeCellEditor(this, cellRenderer));
				this.registerListeners();
			}
		}
	}

	/**
	 * 控件关联的Map对象发生改变时，重新构建所有节点创建树控件
	 */
	public void reload() {
		if (currentMap != null) {
			this.setModel(getTreeModel());
		}
	}

	public void paint(Graphics g) {
		if (!Beans.isDesignTime()) {
			super.paint(g);
		} else {
			g.drawString("LayersTree", this.getWidth() / 2 - 30, this.getHeight() / 2);
		}
	}

	public boolean isPathEditable(TreePath path) {
		Object lastPathComponent = path.getLastPathComponent();
		DefaultMutableTreeNode node = (DefaultMutableTreeNode) lastPathComponent;
		Object obj = node.getUserObject();
		TreeNodeData controlNodeData = (TreeNodeData) obj;
		NodeDataType type = controlNodeData.getType();
		if (type.equals(NodeDataType.LAYER) || type.equals(NodeDataType.LAYER_GROUP)) {
			return true;
		}
		return false;
	}

	// 返回位于(x,y)位置的HitTestInfo。当没有内容时，返回NULL
	public HitTestInfo hitTest(int x, int y) {
		HitTestInfo result = null;

		TreePath path = this.getPathForLocation(x, y);
		if (path != null) {
			Object object = path.getLastPathComponent();
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) object;

			int offset = x - this.getUI().getPathBounds(this, path).x;
			/*
			 * 修改为使用Render来计算点击的Icon类型 modified by gouyu 2010-12-24
			 */
			result = ((LayersTreeCellRenderer) this.getCellRenderer()).getHitTestIconType(node, offset);
		}

		return result;
	}

	private TreeModel getTreeModel() {
		TreeNodeData mapData = new TreeNodeData(currentMap.getName(), NodeDataType.UNKNOWN);
		DefaultMutableTreeNode root = new DefaultMutableTreeNode(mapData);
		if (currentMap.getWorkspace() != null) {
			int count = currentMap.getLayers().getCount();
			for (int layerIndex = 0; layerIndex < count; layerIndex++) {
				Layer layer = currentMap.getLayers().get(layerIndex);
				root.add(getNodeByLayer(layer));
			}
		}
		DefaultTreeModel defaultTreeModel = new DefaultTreeModel(root);
		return defaultTreeModel;
	}

	/**
	 * modify by xuzw 2010-07-19 根据图层获取树节点，为了在Layer3DTree中能使用，修改为protected modified by gouyu 2010-12-23 使用单一出口重构，增加对THEMERANGE、THEMEUNIQUE、THEMECUSTOM类型的编辑的控制
	 * 
	 * @param layer
	 * @return
	 */
	protected DefaultMutableTreeNode getNodeByLayer(Layer layer) {
		DefaultMutableTreeNode result = null;

		Dataset dataset = layer.getDataset();
		if (dataset == null) {
			// 分组图层节点的构建
			if (layer instanceof LayerGroup) {
				result = getGroupNodeByLayer(layer);
			} else {
				result = new DefaultMutableTreeNode(new TreeNodeData(layer, NodeDataType.LAYER));
			}
		} else {
			Theme theme = layer.getTheme();
			if (theme == null) {
				if (dataset.getType().equals(DatasetType.IMAGE)) {
					result = new DefaultMutableTreeNode(new TreeNodeData(layer, NodeDataType.LAYER_IMAGE));
				} else if (dataset.getType().equals(DatasetType.GRID)) {
					result = new DefaultMutableTreeNode(new TreeNodeData(layer, NodeDataType.LAYER_GRID));
				} else if (dataset.getType().equals(DatasetType.GRIDCOLLECTION)) {
					result = new DefaultMutableTreeNode(new TreeNodeData(layer, NodeDataType.DATASET_GRID_COLLECTION));
				} else if (dataset.getType().equals(DatasetType.IMAGECOLLECTION)) {
					result = new DefaultMutableTreeNode(new TreeNodeData(layer, NodeDataType.DATASET_IMAGE_COLLECTION));
				} else {
					result = new DefaultMutableTreeNode(new TreeNodeData(layer, NodeDataType.LAYER));
					if (dataset.getType().equals(DatasetType.WMS)) {
						LayerSettingImage layerSettingImage = (LayerSettingImage) layer.getAdditionalSetting();
						String[] visibleSubLayers = layerSettingImage.getVisibleSubLayers();
						for (int i = 0; i < visibleSubLayers.length; i++) {
							DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(new TreeNodeData(visibleSubLayers[i], NodeDataType.WMSSUB_LAYER));
							result.add(childNode);
						}
					}
				}
			} else {
				int type = theme.getType().value();

				/*
				 * 如果是1(ThemeUnique)、2(ThemeRange)、8(ThemeCustom)就使用自己的构造 以在专题图的基础上增加编辑功能 modified by gouyu 2010-12-23
				 */
				if (type != 1 && type != 2 && type != 8) {
					result = new DefaultMutableTreeNode(new TreeNodeData(layer, NodeDataType.LAYER_THEME));
				}
				switch (type) {
				// ThemeType.UNIQUE
				case 1: {
					result = new DefaultMutableTreeNode(new TreeNodeData(layer, NodeDataType.THEME_UNIQUE));
					ThemeUnique themeUnique = (ThemeUnique) theme;
					for (int i = 0; i < themeUnique.getCount(); i++) {
						ThemeUniqueItem uniqueItem = themeUnique.getItem(i);
						TreeNodeData itemData = new TreeNodeData(uniqueItem, NodeDataType.THEME_UNIQUE_ITEM, layer);
						result.add(new DefaultMutableTreeNode(itemData));
					}
				}
					break;
				// ThemeType.RANGE
				case 2: {
					result = new DefaultMutableTreeNode(new TreeNodeData(layer, NodeDataType.THEME_RANGE));
					ThemeRange range = (ThemeRange) theme;
					for (int i = 0; i < range.getCount(); i++) {
						ThemeRangeItem rangeItem = range.getItem(i);
						TreeNodeData itemData = new TreeNodeData(rangeItem, NodeDataType.THEME_RANGE_ITEM, layer);
						result.add(new DefaultMutableTreeNode(itemData));
					}
				}
					break;
				// ThemeType.GRAPH
				case 3: {
					ThemeGraph graph = (ThemeGraph) theme;

					for (int i = 0; i < graph.getCount(); i++) {
						ThemeGraphItem graphItem = graph.getItem(i);
						TreeNodeData itemData = new TreeNodeData(graphItem, NodeDataType.THEME_GRAPH_ITEM, layer);

						result.add(new DefaultMutableTreeNode(itemData));
					}
				}
					break;
				// ThemeType.LABEL
				case 7: {
					ThemeLabel themeLabel = (ThemeLabel) theme;

					for (int i = 0; i < themeLabel.getCount(); i++) {
						ThemeLabelItem labelItem = themeLabel.getItem(i);
						TreeNodeData itemData = new TreeNodeData(labelItem, NodeDataType.THEME_LABEL_ITEM, layer);

						result.add(new DefaultMutableTreeNode(itemData));
					}
				}
					break;
				// ThemeType.CUSTOM
				case 8: {
					result = new DefaultMutableTreeNode(new TreeNodeData(layer, NodeDataType.THEME_CUSTOM));
				}
					break;
				// ThemeType.GRIDUNIQUE
				case 11: {
					ThemeGridUnique gridUnique = (ThemeGridUnique) theme;
					for (int i = 0; i < gridUnique.getCount(); i++) {
						ThemeGridUniqueItem gridUniqueItem = gridUnique.getItem(i);
						TreeNodeData itemData = new TreeNodeData(gridUniqueItem, NodeDataType.THEME_GRID_UNIQUE_ITEM, layer);
						result.add(new DefaultMutableTreeNode(itemData));
					}
				}
					break;
				// ThemeType.GRIDRANGE
				case 12: {
					ThemeGridRange gridRange = (ThemeGridRange) theme;
					for (int i = 0; i < gridRange.getCount(); i++) {
						ThemeGridRangeItem gridRangeItem = gridRange.getItem(i);
						TreeNodeData itemData = new TreeNodeData(gridRangeItem, NodeDataType.THEME_GRID_RANGE_ITEM, layer);
						result.add(new DefaultMutableTreeNode(itemData));
					}
				}
					break;
				default:
					break;
				}
			}
		}

		return result;
	}

	// 还有Group和Group里面的Layer的事件注册没有写
	private HashMap<LayerGroup, DefaultMutableTreeNode> groupNodeMap;

	private DefaultMutableTreeNode createLayerGroupNode(Layer layer) {

		if (groupNodeMap == null) {
			groupNodeMap = new HashMap<LayerGroup, DefaultMutableTreeNode>();
		}

		LayerGroup group = (LayerGroup) layer;
		group.addLayerAddedListener(new GroupLayerAddedListener());
		group.addLayerRemovedListener(new GroupLayerRemovedListener());

		DefaultMutableTreeNode result = new DefaultMutableTreeNode(new TreeNodeData(layer, NodeDataType.LAYER_GROUP));

		groupNodeMap.put((LayerGroup) layer, result);

		return result;
	}

	private class GroupLayerAddedListener implements LayerAddedListener {
		public void layerAdded(LayerAddedEvent event) {
			LayerGroup group = (LayerGroup) event.getSource();
			DefaultMutableTreeNode parentNode = groupNodeMap.get(group);

			Layer layer = event.getLayer();
			DefaultTreeModel model = (DefaultTreeModel) getModel();
			// 将节点插入到与图层索引一致处
			model.insertNodeInto(getNodeByLayer(layer), parentNode, event.getIndex());
		}
	};

	private class GroupLayerRemovedListener implements LayerRemovedListener {
		public void layerRemoved(LayerRemovedEvent event) {
			LayerGroup group = (LayerGroup) event.getSource();
			DefaultMutableTreeNode parentNode = groupNodeMap.get(group);

			DefaultTreeModel model = (DefaultTreeModel) getModel();
			model.removeNodeFromParent((MutableTreeNode) parentNode.getChildAt(event.getIndex()));
		}
	};

	protected DefaultMutableTreeNode getGroupNodeByLayer(Layer layer) {
		DefaultMutableTreeNode result = null;

		if (layer instanceof LayerGroup) {
			result = createLayerGroupNode(layer);
			LayerGroup layerGroup = (LayerGroup) layer;
			int count = layerGroup.getCount();

			for (int i = 0; i < count; i++) {
				Layer child = layerGroup.get(i);
				result.add(getGroupNodeByLayer(child));
			}
		} else {
			result = getNodeByLayer(layer);
		}

		return result;
	}

	private void removeLayersControlNode() {
		try {
			TreePath[] paths = this.getSelectionPaths();
			for (int i = 0; i < paths.length; i++) {
				TreePath path = paths[i];
				Object lastPathComponent = path.getLastPathComponent();
				DefaultMutableTreeNode node = (DefaultMutableTreeNode) lastPathComponent;
				Object obj = node.getUserObject();
				TreeNodeData controlNodeData = (TreeNodeData) obj;
				Object itemObj = controlNodeData.getData();
				if (itemObj instanceof Layer) {
					Layer layer = (Layer) itemObj;
					LayerGroup parentGroup = layer.getParentGroup();
					if (parentGroup != null) {
						parentGroup.remove(layer);
					} else {
						currentMap.getLayers().remove(layer.getName());
					}
				}
				if (controlNodeData.getType().equals(NodeDataType.THEME_GRAPH_ITEM)) {
					ThemeGraphItem item = (ThemeGraphItem) itemObj;
					Layer layer = controlNodeData.getParentLayer();
					ThemeGraph graph = (ThemeGraph) layer.getTheme();
					graph.remove(graph.indexOf(item.getGraphExpression()));
					((DefaultTreeModel) getModel()).removeNodeFromParent(node);
				}
				if (controlNodeData.getType().equals(NodeDataType.THEME_UNIQUE_ITEM)) {
					ThemeUniqueItem item = (ThemeUniqueItem) itemObj;
					Layer layer = controlNodeData.getParentLayer();
					ThemeUnique unique = (ThemeUnique) layer.getTheme();
					unique.remove(unique.indexOf(item.getUnique()));
					((DefaultTreeModel) getModel()).removeNodeFromParent(node);
				}
			}
			currentMap.refresh();
		} catch (Exception e) {
		}
	}

	private void unRegisterListeners() {
		if (currentMap.getWorkspace() != null) {
			currentMap.getLayers().removeLayerAddedListener(getLayerAddedListener());
			currentMap.getLayers().removeLayerRemovedListener(getLayerRemovedListener());
			currentMap.getLayers().addLayerGroupAddedListener(getLayerGroupAddedListener());
			currentMap.getLayers().addLayerGroupRemovedListener(getLayerGroupRemovedListener());

			removeKeyListener(keyAdapter);
			removeMouseListener(mouseAdapter);
		}
	}

	private void registerListeners() {
		if (currentMap.getWorkspace() != null) {
			currentMap.getLayers().addLayerAddedListener(getLayerAddedListener());
			currentMap.getLayers().addLayerRemovedListener(getLayerRemovedListener());
			currentMap.getLayers().addLayerGroupAddedListener(getLayerGroupAddedListener());
			currentMap.getLayers().addLayerGroupRemovedListener(getLayerGroupRemovedListener());

			addKeyListener(getKeyListener());
			addMouseListener(getMouseListener());
		}
	}

	LayerAddedListener getLayerAddedListener() {
		if (layerAddedListener == null) {
			layerAddedListener = new TreeLayerAddedListener();
		}
		return layerAddedListener;
	}

	private class TreeLayerAddedListener implements LayerAddedListener {

		public void layerAdded(LayerAddedEvent event) {
			Layer layer = event.getLayer();
			DefaultTreeModel model = (DefaultTreeModel) getModel();
			DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) model.getRoot();
			// 将节点插入到与图层索引一致处
			model.insertNodeInto(getNodeByLayer(layer), rootNode, currentMap.getLayers().indexOf(layer.getName()));
		}
	}

	LayerRemovedListener getLayerRemovedListener() {
		if (layerRemovedListener == null) {
			layerRemovedListener = new TreeLayerRemovedListener();
		}
		return layerRemovedListener;
	}

	private class TreeLayerRemovedListener implements LayerRemovedListener {

		public void layerRemoved(LayerRemovedEvent event) {
			DefaultTreeModel model = (DefaultTreeModel) getModel();
			Object obj = model.getChild(model.getRoot(), event.getIndex());
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) obj;
			model.removeNodeFromParent(node);
		}
	}

	LayerGroupAddedListener getLayerGroupAddedListener() {
		if (layerGroupAddedListener == null) {
			layerGroupAddedListener = new TreeLayerGroupAddedListener();
		}

		return layerGroupAddedListener;
	}

	private class TreeLayerGroupAddedListener implements LayerGroupAddedListener {
		public void layerGroupAdded(LayerGroupAddedEvent e) {
			LayerGroup layerGroup = e.getAddedGroup();
			LayerGroup parentGroup = e.getParentGroup();

			if (parentGroup != null) {
				DefaultMutableTreeNode parentNode = groupNodeMap.get(parentGroup);
				if (parentNode != null) {
					DefaultTreeModel model = (DefaultTreeModel) getModel();
					model.insertNodeInto(getGroupNodeByLayer(layerGroup), parentNode, e.getIndex());
				}
			} else {
				LayerGroup addedGroup = e.getAddedGroup();
				DefaultTreeModel model = (DefaultTreeModel) getModel();
				DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) model.getRoot();
				// 将节点插入到与图层索引一致处
				model.insertNodeInto(getGroupNodeByLayer(addedGroup), rootNode, e.getIndex());
			}
		}
	}

	LayerGroupRemovedListener getLayerGroupRemovedListener() {
		if (layerGroupRemovedListener == null) {
			layerGroupRemovedListener = new TreeLayerGroupRemovedListener();
		}

		return layerGroupRemovedListener;
	}

	private class TreeLayerGroupRemovedListener implements LayerGroupRemovedListener {
		public void layerGroupRemoved(LayerGroupRemovedEvent event) {
			LayerGroup layerGroup = event.getRemovedGroup();
			LayerGroup parentGroup = event.getParentGroup();

			if (parentGroup != null) {
				DefaultMutableTreeNode parentNode = groupNodeMap.get(parentGroup);
				;
				DefaultMutableTreeNode removedNode = groupNodeMap.get(layerGroup);
				;

				if (parentNode != null && removedNode != null) {
					parentNode.remove(removedNode);
				}
			} else {
				DefaultTreeModel model = (DefaultTreeModel) getModel();
				DefaultMutableTreeNode removedNode = groupNodeMap.get(layerGroup);
				;

				if (removedNode != null) {
					model.removeNodeFromParent(removedNode);
				}
			}
		}
	}

	KeyAdapter getKeyListener() {
		if (keyAdapter == null) {
			keyAdapter = new TreeKeyListener();
		}
		return keyAdapter;
	}

	private class TreeKeyListener extends KeyAdapter {

		public void keyTyped(KeyEvent e) {
			int keyCode = e.getKeyChar();
			switch (keyCode) {
			case KeyEvent.VK_DELETE:
				removeLayersControlNode();
				break;
			default:
				break;
			}
		}
	}

	MouseAdapter getMouseListener() {
		if (mouseAdapter == null) {
			mouseAdapter = new TreeMouseListener();
		}
		return mouseAdapter;
	}

	private class TreeMouseListener extends MouseAdapter {
		public void mouseClicked(MouseEvent e) {
			TreePath path = LayersTree.this.getPathForLocation(e.getX(), e.getY());
			if (path != null) {
				HitTestInfo hitTestInfo = hitTest(e.getX(), e.getY());
				if (hitTestInfo != null) {

					TreeNodeData nodeData = hitTestInfo.getData();
					Object obj = nodeData.getData();

					int type = hitTestInfo.getIconType().value();

					switch (type) {
					case 1: {
						if (obj instanceof Layer) {
							Layer layer = (Layer) obj;
							layer.setVisible(!layer.isVisible());
						}
						if (obj instanceof ThemeUniqueItem) {
							ThemeUniqueItem item = (ThemeUniqueItem) obj;
							item.setVisible(!item.isVisible());
						}
						if (obj instanceof ThemeRangeItem) {
							ThemeRangeItem item = (ThemeRangeItem) obj;
							item.setVisible(!item.isVisible());
						}
						if (obj instanceof ThemeGridUniqueItem) {
							ThemeGridUniqueItem item = (ThemeGridUniqueItem) obj;
							item.setVisible(!item.isVisible());
						}
						if (obj instanceof ThemeGridRangeItem) {
							ThemeGridRangeItem item = (ThemeGridRangeItem) obj;
							item.setVisible(!item.isVisible());
						}
						if (obj instanceof ThemeLabelItem) {
							ThemeLabelItem item = (ThemeLabelItem) obj;
							item.setVisible(!item.isVisible());
						}
					}
						break;
					case 2: {
						if (obj instanceof Layer) {
							Layer layer = (Layer) obj;
							layer.setSelectable(!layer.isSelectable());
						}
					}
						break;
					case 3: {
						if (obj instanceof Layer) {
							Layer layer = (Layer) obj;
							layer.setEditable(!layer.isEditable());
						}
					}
						break;
					case 4: {
						if (obj instanceof Layer) {
							Layer layer = (Layer) obj;
							layer.setSnapable(!layer.isSnapable());
						}
					}
						break;
					default:
						break;
					}
				}
				updateUI();
				currentMap.refresh();
			}
		}
	}

	/**
	 * DragGestureListener:当该（子）类的对象检测到拖动启动动作时，调用此接口
	 * 
	 * @author wangdy
	 *
	 */
	private class LayersTreeDragGestureListener implements DragGestureListener {
		public void dragGestureRecognized(DragGestureEvent dge) {
			Point clickPoint = dge.getDragOrigin();
			TreePath path = getClosestPathForLocation(clickPoint.x, clickPoint.y);
			draggedNode = (DefaultMutableTreeNode) path.getLastPathComponent();
			draggedNodeIndex = ((DefaultMutableTreeNode) LayersTree.this.getModel().getRoot()).getIndex(draggedNode);
			dropTargetNodeIndex = -1;

			// 判断拖拽的两个节点的父节点是否是根节点
			if (getRowForPath(getSelectionPath()) == -1 || !draggedNode.getParent().equals(getModel().getRoot()))
				return;
			Transferable trans = new RJLTransferable(draggedNode);
			dge.startDrag(DragSource.DefaultMoveDrop, trans, new MyDragSourceAdapter());
		}
	}

	private class RJLTransferable implements Transferable {
		Object object;

		public RJLTransferable(Object o) {
			object = o;
		}

		public Object getTransferData(DataFlavor df) throws UnsupportedFlavorException, IOException {
			if (isDataFlavorSupported(df))
				return object;
			else
				throw new UnsupportedFlavorException(df);
		}

		public boolean isDataFlavorSupported(DataFlavor df) {
			return (df.equals(localObjectFlavor));
		}

		public DataFlavor[] getTransferDataFlavors() {
			return supportedFlavors;
		}
	}

	/**
	 * 用于提供所涉及的 DropTarget 的 DnD 操作的通知
	 * 
	 * @author wangdy
	 */
	private class LayersTreeDropTargetAdapter extends DropTargetAdapter {
		private TreePath treePath = null;
		// 用于存上一次的矩形
		private Rectangle recordBounds = null;
		private DefaultMutableTreeNode oldNode = null;

		private int oldRow = 0;
		// 标志是向上还是向下拖动，true表示向上
		private boolean isUp = false;

		public void drop(DropTargetDropEvent dtde) {
			recordBounds = null;
			oldNode = null;
			oldRow = getRowForPath(getSelectionPath());
			try {
				if (oldRow == -1 || dropTargetNodeIndex == -1 || draggedNodeIndex == dropTargetNodeIndex)
					return;
				DefaultMutableTreeNode parent = (DefaultMutableTreeNode) getModel().getRoot();
				((DefaultTreeModel) getModel()).removeNodeFromParent(draggedNode);
				((DefaultTreeModel) getModel()).insertNodeInto(draggedNode, parent, dropTargetNodeIndex);
				currentMap.getLayers().moveTo(draggedNodeIndex, dropTargetNodeIndex);
				currentMap.refresh();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		public void dragOver(DropTargetDragEvent dtde) {
			Point dragPoint = dtde.getLocation();
			if (dragPoint == null)
				return;
			treePath = getPathForLocation(dragPoint.x, dragPoint.y);

			if (treePath == null) {
				dropTargetNode = null;
				dropTargetNodeIndex = -1;
				return;
			} else {
				dropTargetNode = (DefaultMutableTreeNode) treePath.getLastPathComponent();
				// 如果目标节点跟被拖拽节点的父节点不同，则将目标节点回滚到上一次
				if (!dropTargetNode.getParent().equals(draggedNode.getParent())) {
					dropTargetNode = oldNode;
					dropTargetNodeIndex = -1;
					return;
				}
				if (oldNode == null || oldRow == -1) {
					oldNode = dropTargetNode;
					oldRow = getRowForPath(getSelectionPath());
				}
			}
			if (oldNode != null)
				repaintTree();
		}

		/**
		 * 重新绘制树
		 */
		private void repaintTree() {
			Graphics2D graphics2D = (Graphics2D) getGraphics();
			Color color = graphics2D.getColor();
			Rectangle bounds = getPathBounds(treePath);
			dropTargetNodeIndex = ((DefaultMutableTreeNode) getModel().getRoot()).getIndex(dropTargetNode);

			// 被拖拽的节点索引大于目标节点索引，则表示向上拖拽，否则表示向下，在相应的位置画线
			if (draggedNodeIndex > dropTargetNodeIndex) {
				graphics2D.drawLine(bounds.x, bounds.y, bounds.x + bounds.width, bounds.y);
				isUp = true;
			} else if (draggedNodeIndex < dropTargetNodeIndex) {
				graphics2D.drawLine(bounds.x, bounds.y + bounds.height, bounds.x + bounds.width, bounds.y + bounds.height);
				isUp = false;
			}

			if (recordBounds == null) {
				recordBounds = bounds;
			} else {
				if (!recordBounds.equals(bounds)) {
					// 将graphics2D置为白色，用于清除上一次的线
					graphics2D.setColor(Color.white);
					if (isUp) {
						graphics2D.drawLine(recordBounds.x, recordBounds.y, recordBounds.x + recordBounds.width, recordBounds.y);
					} else {
						graphics2D.drawLine(recordBounds.x, recordBounds.y + recordBounds.height, recordBounds.x + recordBounds.width,
								recordBounds.y + recordBounds.height);
					}
				}
			}
			recordBounds = bounds;
			oldNode = dropTargetNode;
			oldRow = getRowForPath(getSelectionPath());

			JPanel panel = (JPanel) getCellRenderer().getTreeCellRendererComponent(LayersTree.this, oldNode, false, isExpanded(treePath),
					getModel().isLeaf(oldNode), oldRow, false);
			panel.repaint();
			// 将graphics2D置回原来的颜色
			graphics2D.setColor(color);
		}
	}

	/**
	 * Drag 和 Drop 操作为用户提供合适的“拖动结束”反馈
	 * 
	 * @author wangdy
	 */
	private class MyDragSourceAdapter extends DragSourceAdapter {
		public void dragDropEnd(DragSourceDropEvent dsde) {
			dropTargetNode = null;
			draggedNode = null;
			LayersTree.this.repaint();
		}
	}
}
